package com.hee.erp.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hee.erp.constant.ConstRight;
import com.hee.erp.enums.AuditStatusEnum;
import com.hee.erp.enums.WorkflowNodeTypeEnum;
import com.hee.erp.filter.LoginContextHolder;
import com.hee.erp.modules.entity.*;
import com.hee.erp.modules.mapper.AuditLeaveMapper;
import com.hee.erp.modules.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hee.erp.vo.leave.AuditFlowNode;
import com.hee.erp.vo.page.AuditLeavePageParams;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author weizehong
 * @since 2022-05-18
 */
@Service
@Transactional
public class AuditLeaveServiceImpl extends ServiceImpl<AuditLeaveMapper, AuditLeave> implements IAuditLeaveService {

    @Autowired
    IWf2RightService wf2RightService;

    @Autowired
    IWfMainService wfMainService;

    @Autowired
    IAuditFlowService auditFlowService;

    @Autowired
    IAuditLeaveTypeService auditLeaveTypeService;

    @Autowired
    ISysUserService sysUserService;

    @Autowired
    IAuditResultService auditResultService;

    @Override
    public void saveDetail(AuditLeave vo) {
        vo.setAuditStatus(AuditStatusEnum.AUDITING);
        this.save(vo);

        //保存审批结果
        AuditResult auditResult = new AuditResult();
        auditResult.setAuditMainId(vo.getId());
        auditResult.setAuditStatus(vo.getAuditStatus());
        auditResultService.save(auditResult);

        if (vo.getAuditStatus().equals(AuditStatusEnum.AUDITING)) {
            //保存审批流
            auditFlowService.saveDetail(ConstRight.ASK_LEAVE_ROUTE_NAME, vo.getId());
        }
    }

    @Override
    public IPage listByPage(AuditLeavePageParams pageParams) {
        IPage<AuditLeave> page = new Page<>();
        page.setCurrent(pageParams.getCurrent());
        page.setSize(pageParams.getPageSize());

        QueryWrapper<AuditLeave> queryWrapper = createQueryWrapper(pageParams);
        this.page(page, queryWrapper);

        List<AuditLeave> records = page.getRecords();
        setForeignKeys(records);
        return page;
    }

    @Override
    public AuditLeave getDetailById(String id) {
        AuditLeave auditLeave = this.getById(id);

        setCommonForeignKey(auditLeave);
        setDetailsForeignKey(auditLeave);
        return auditLeave;
    }

    private void setDetailsForeignKey(AuditLeave auditLeave) {

        //审核节点
//        AuditFlowNode startNode = new AuditFlowNode();
//        startNode.setNodeType(WorkflowNodeTypeEnum.START);
//        startNode.setAuditorUserId(auditLeave.getCreateUser());
//        startNode.setNodeName(startNode.getNodeName());
//        startNode.setShowUserName(auditLeave.getCreateUserName());
//        startNode.setAuditStatus(AuditStatusEnum.AUDITING);
//        startNode.setAuditStatusName("已提交");
//        startNode.setAuditTime(auditLeave.getCreateTime());
        AuditFlow startAuditFlow = auditFlowService.getStartNodeByMainId(auditLeave.getId());
        AuditFlowNode startNode = new AuditFlowNode();
        startNode.setId(startAuditFlow.getId());
        startNode.setAuditMainId(startAuditFlow.getAuditMainId());
        startNode.setNodeType(startAuditFlow.getNodeType());
        startNode.setAuditorUserId(startAuditFlow.getAuditorUserId());
        startNode.setNodeName(startAuditFlow.getNodeName());
        startNode.setShowUserName(auditLeave.getCreateUserName());
        startNode.setAuditStatus(startAuditFlow.getAuditStatus());
        startNode.setAuditStatusName("已提交");
        startNode.setAuditTime(startAuditFlow.getAuditTime());

        List<AuditFlow> allAuditFlowList = auditFlowService.listAuditNodeByMainId(auditLeave.getId());
        buildAuditFlowNode(startNode, allAuditFlowList);

        auditLeave.setAuditFlowNode(startNode);


    }

    private void buildAuditFlowNode(AuditFlowNode parentNode, List<AuditFlow> allAuditFlowList) {
        AuditFlow nextNode = null;
        //查询当前节点的下一个节点
        if (StringUtils.isBlank(parentNode.getId())) {
            nextNode = allAuditFlowList.stream().filter(item -> item.getParentId() == null || item.getParentId().equals("")).findFirst().orElse(null);
        } else {
            nextNode = allAuditFlowList.stream().filter(item -> item.getParentId() != null && item.getParentId().equals(parentNode.getId())).findFirst().orElse(null);
        }
        if (nextNode != null) {
            AuditFlowNode nextAuditFlowNode = new AuditFlowNode();
            nextAuditFlowNode.setId(nextNode.getId());
            nextAuditFlowNode.setNodeType(nextNode.getNodeType());
            nextAuditFlowNode.setNodeName(nextNode.getNodeName());
            if (StringUtils.isNotBlank(nextNode.getAuditorUserId())) {
                nextAuditFlowNode.setAuditorUserId(nextNode.getAuditorUserId());
                SysUser sysUser = sysUserService.getById(nextNode.getAuditorUserId());
                if (sysUser != null) {
                    nextAuditFlowNode.setShowUserName(sysUser.getUserName());
                }
            }
            nextAuditFlowNode.setAuditMainId(nextNode.getAuditMainId());
            nextAuditFlowNode.setAuditStatus(nextNode.getAuditStatus());
            nextAuditFlowNode.setAuditStatusName(nextNode.getAuditStatus().equals(AuditStatusEnum.DRAFT) ? "等待审批": nextNode.getAuditStatus().getName());
            nextAuditFlowNode.setAuditTime(nextNode.getAuditTime());
            nextAuditFlowNode.setAuditRemark(nextNode.getAuditRemark());
            parentNode.setNext(nextAuditFlowNode);

            buildAuditFlowNode(nextAuditFlowNode, allAuditFlowList);
        }
    }

    private QueryWrapper<AuditLeave> createQueryWrapper(AuditLeavePageParams pageParams) {
        QueryWrapper<AuditLeave> queryWrapper = new QueryWrapper<>();
        if (pageParams.getCondition() != null) {
            //请假类型
            if (StringUtils.isNotBlank(pageParams.getCondition().getLeaveTypeId())) {
                queryWrapper.lambda().eq(AuditLeave::getLeaveTypeId, pageParams.getCondition().getLeaveTypeId());
            }
            //请假原因
            if (StringUtils.isNotBlank(pageParams.getCondition().getLeaveReason())) {
                queryWrapper.lambda().like(AuditLeave::getLeaveReason, pageParams.getCondition().getLeaveReason());
            }
            String currentUserId = LoginContextHolder.get().getUserId();
            //是否只显示自己的请假
            if (pageParams.getCondition().getOnlyCurrentUser() != null && pageParams.getCondition().getOnlyCurrentUser() == 1) {
                queryWrapper.lambda().eq(AuditLeave::getCreateUser, currentUserId);
            } else {
                queryWrapper.lambda().ne(AuditLeave::getCreateUser, currentUserId);
                queryWrapper.lambda().inSql(AuditLeave::getId, String.format(" select audit_main_id from t_audit_flow where auditor_user_id = '%s' ", currentUserId));
            }
        }

        queryWrapper.lambda().orderByDesc(AuditLeave::getCreateTime);
        return queryWrapper;
    }

    private void setForeignKeys(List<AuditLeave> records) {

        for (AuditLeave leave : records) {
            setCommonForeignKey(leave);
        }
    }

    private void setCommonForeignKey(AuditLeave leave) {
        //请假人 createUserName
        if (StringUtils.isNotBlank(leave.getCreateUser())) {
            SysUser sysUser = sysUserService.getById(leave.getCreateUser());
            if (sysUser != null) {
                leave.setCreateUserName(sysUser.getUserName());
            }
        }

        //请休假类型
        if (StringUtils.isNotBlank(leave.getLeaveTypeId())) {
            AuditLeaveType leaveType = auditLeaveTypeService.getById(leave.getLeaveTypeId());
            if (leaveType != null) {
                leave.setLeaveTypeName(leaveType.getTypeName());
            }
        }

        //审核状态、驳回原因、当前审核人 新版本
        AuditResult auditResult = auditResultService.getByMainId(leave.getId());
        if (auditResult != null) {
            leave.setAuditStatus(auditResult.getAuditStatus());
            leave.setAuditStatusName(auditResult.getAuditStatus().getName());
            leave.setAuditRemark(auditResult.getAuditRemark());
            leave.setApproveTime(auditResult.getAuditTime());
            if(StringUtils.isNotBlank(auditResult.getAuditingAuditorId()))  {
                leave.setAuditingAuditorId(auditResult.getAuditingAuditorId());
                SysUser sysUser = sysUserService.getById(auditResult.getAuditingAuditorId());
                if (sysUser != null) {
                    leave.setAuditingAuditorName(sysUser.getUserName());
                }
            }
        }

        //审核状态、驳回原因、当前审核人 旧版本
        /*
        AuditStatusEnum auditStatus = AuditStatusEnum.AUDITING;
        //获取审核节点
        List<AuditFlow> approveFlowList = auditFlowService.listAuditNodeByMainId(leave.getId());
        if (approveFlowList != null && approveFlowList.size() > 0) {
            //获取第一个审核节点
            AuditFlow currentNode = approveFlowList.stream().filter(item -> StringUtils.isBlank(item.getParentId())).findFirst().orElse(null);
            while (currentNode != null) {
                if (currentNode.getAuditStatus().equals(AuditStatusEnum.REJECT)) {
                    auditStatus = currentNode.getAuditStatus();
                    leave.setAuditRemark(currentNode.getAuditRemark());
                    leave.setAuditingAuditorId(currentNode.getAuditorUserId());
                    SysUser sysUser = sysUserService.getById(currentNode.getAuditorUserId());
                    if (sysUser != null) {
                        leave.setAuditingAuditorName(sysUser.getUserName());
                    }
                    break;
                }
                if (currentNode.getAuditStatus().equals(AuditStatusEnum.AUDITING)) {
                    auditStatus = currentNode.getAuditStatus();
                    leave.setAuditingAuditorId(currentNode.getAuditorUserId());
                    SysUser sysUser = sysUserService.getById(currentNode.getAuditorUserId());
                    if (sysUser != null) {
                        leave.setAuditingAuditorName(sysUser.getUserName());
                    }

                    break;
                }
                if (currentNode.getAuditStatus().equals(AuditStatusEnum.DRAFT)) {
                    auditStatus = AuditStatusEnum.AUDITING;
                    break;
                }
                if (currentNode.getAuditStatus().equals(AuditStatusEnum.PASS)) {
                    String currentNodeId = currentNode.getId();
                    //批准时间
                    leave.setApproveTime(currentNode.getAuditTime());
                    currentNode = approveFlowList.stream().filter(item -> item.getParentId().equals(currentNodeId)).findFirst().orElse(null);
                }
            }

            if (currentNode == null) {
                auditStatus = AuditStatusEnum.PASS;
            }
        }

        leave.setAuditStatus(auditStatus);
        leave.setAuditStatusName(auditStatus.getName());
         */

    }
}
